package com.synjones.handsetS8;

import android.content.Context;
import android.util.Log;

import java.io.File;
import java.io.IOException;

import android_serialport_api.SerialPort;

/**
 * Created by zhaodianbo on 2017-1-17.
 */
public class BarReader {
    Context mContext;
    SerialPort serialPort;
    DataTransChannel dataTransChannel;
    boolean open;
    volatile  boolean isScanning =false;
    private long TIMEOUT =3000;

    public BarReader(Context mContext){
        this.mContext=mContext;
    }

    public void powerOn() {
        WtWdPowerUtils.setFingerPower(mContext);
        try {
            Thread.sleep(500);//使模块上电完成
        } catch (InterruptedException e) {}
    }

    public void powerOff() {
        WtWdPowerUtils.closeFingerPower(mContext);
    }
    public int open() {
        if(open) {
            return 0;
        }
        open=false;

        powerOn();
        try {
            serialPort = new SerialPort(new File("/dev/ttyMT1"), 9600, 0);
            dataTransChannel=new DataTransChannel();
            dataTransChannel.setInOutStream(serialPort.getInputStream(),serialPort.getOutputStream());
            dataTransChannel.open();
        } catch (IOException e) {
            e.printStackTrace();
            return -1;
        }
        open=true;
        return 0;
    }



    public int close() {
        stopScan();
        powerOff();
        if(dataTransChannel!=null)
            dataTransChannel.close();
        if(serialPort!=null)
            serialPort.close();

        dataTransChannel=null;
        serialPort=null;
        open=false;
        return 0;
    }

    public boolean isOpen() {
        return open;
    }

    public BarExeCmdResult setRestoreFactorySetting(){
        return exeCmd("0001000");
    }


    public BarExeCmdResult setOutputSettingCodeEnable(boolean enable){
        return setEnable("0002010","0002000",enable);
    }



    public BarExeCmdResult setSettingEnable(boolean enable){
        return setEnable("0006010","0006000",enable);
    }


    public BarExeCmdResult setBeepEnable(boolean enable){
        return setEnable("0203010","0203000",enable);
    }

    public BarExeCmdResult setSuffixValue(String byteValue){
        return setValue("0310000",null,byteValue);
    }

    public BarExeCmdResult setAimEnable(boolean enable){
        return setEnable("0308030","0308000",enable);
    }

    public BarExeCmdResult setSuffixEnable(boolean enable){
        return setEnable("0309010","0309000",enable);
    }

    public BarExeCmdResult setMatrixEnable(boolean enable){
        return setEnable("0406020","0406010",enable);
    }

    public BarExeCmdResult setEnable(String cmdEnable,String cmdDisable,boolean enable){
        byte cmd[];
        if(enable)
            cmd=packSettingCmd(cmdEnable,null,null);
        else
            cmd=packSettingCmd(cmdDisable,null,null);
        sendCmd(cmd);
        return getExeResult();
    }

    public BarExeCmdResult setValue(String cmdStr,String valueStr,String valueByte){
        byte cmd[];
        cmd=packSettingCmd(cmdStr,valueStr,valueByte);
        sendCmd(cmd);
        return getExeResult();
    }

    public BarExeCmdResult exeCmd(String cmdStr){
        byte cmd[];
        cmd=packSettingCmd(cmdStr,null,null);
        sendCmd(cmd);
        return getExeResult();
    }



    public int sendCmd(byte[] cmd){
        if(dataTransChannel==null) return -1;
        dataTransChannel.sendData(cmd,cmd.length);
        return 0;
    }


    public byte[] packSettingCmd(String cmd,String paraStr,String paraByte){
        int cmdLen=cmd.length();
        String equal="=";
        String prefix="nls";
        String end=";";
        if(paraStr!=null&&paraStr.length()>0) paraStr="\""+paraStr+"\"";
        int paraStrLen=paraStr==null?0:paraStr.length();
        int paraByteLen=paraByte==null?0:paraByte.length();
        cmdLen+=prefix.length()+end.length();
        if(paraByteLen>0||paraStrLen>0){
            cmdLen+=equal.length()+paraStrLen+paraByteLen;
        }
        byte retCmd[]=new byte[cmdLen];
        int index=0;
        System.arraycopy(prefix.getBytes(),0,retCmd,index,prefix.length());
        index+=prefix.length();
        System.arraycopy(cmd.getBytes(),0,retCmd,index,cmd.length());
        index+=cmd.length();
        if(paraStrLen>0 || paraByteLen>0) {
            System.arraycopy(equal.getBytes(), 0, retCmd, index, equal.length());
            index += equal.length();
            if (paraStrLen != 0)
                System.arraycopy(paraStr.getBytes(), 0, retCmd, index, paraStrLen);
            index += paraStrLen;
            if (paraByteLen != 0)
                System.arraycopy(paraByte.getBytes(), 0, retCmd, index, paraByteLen);
            index += paraByteLen;
        }
        System.arraycopy(end.getBytes(),0,retCmd,index,end.length());
        return retCmd;
    }

    public void stopScan(){
        isScanning =false;
    }

    public boolean isScanning(){
        return isScanning;
    }


    public BarExeCmdResult getExeResult(){
        if(dataTransChannel==null)  return new BarExeCmdResult((byte) -1);
        long crt=System.currentTimeMillis();
        byte buffer[]=new byte[1024];
        int offset=0;
        isScanning =true;
        dataTransChannel.clear();
        Log.e("bar","isScanning="+ isScanning);
        while (System.currentTimeMillis()-crt<500 && isScanning){
            int len=dataTransChannel.recvData(buffer,offset);
            if(len>0){
                offset+=len;
            }
            if(offset>0) break;
            MyUtils.sleep(100);
        }
        isScanning=false;
        if(offset<=0) return new BarExeCmdResult((byte) -2);

        return new BarExeCmdResult(buffer[0]);
    }


    public BarScanResult getScanResult(){
        if(dataTransChannel==null)  return new BarScanResult(-1);
        long crt=System.currentTimeMillis();
        byte buffer[]=new byte[1024];
        int offset=0;
        isScanning =true;
        dataTransChannel.clear();
        Log.e("bar","isScanning="+ isScanning);
        long lastReadTime=0;
        boolean isRecvData=false;

        while (System.currentTimeMillis()-crt< TIMEOUT && isScanning){
            int len=dataTransChannel.recvData(buffer,offset);
            if(len>0){
                lastReadTime=System.currentTimeMillis();
                offset+=len;
            }else{
                if(isRecvData && System.currentTimeMillis()-lastReadTime>100) break;
            }

            if(offset>3 && buffer[offset-2]=='\r' && buffer[offset-1]=='\n' ) {
                break;
            }

            if(offset>3) {
                isRecvData=true;
            }
            MyUtils.sleep(20);

        }
        long totalTime=System.currentTimeMillis()-crt;
        isScanning =false;

        if(!isRecvData && totalTime>= TIMEOUT){
            return new BarScanResult(BarScanResult.ERR_TIMEOUT);
        }

        Log.e("bar","isScanning="+ isScanning);
        if(offset==0) return new BarScanResult(BarScanResult.ERR_RECV1);
        if(offset==1) return new BarScanResult(BarScanResult.ERR_RECV2);
        byte bufferMsg[]=new byte[offset-1];
        System.arraycopy(buffer,1,bufferMsg,0,offset-1);
        BarScanResult barScanResult=new BarScanResult(BarScanResult.ERR_OK);
        barScanResult.barMsg=new String(bufferMsg);
        byte bufferBytes[]=new byte[offset];
        System.arraycopy(buffer,0,bufferBytes,0,offset);
        barScanResult.barBytes =bufferBytes;
        barScanResult.setTotalTimeUse(""+totalTime);
        return barScanResult;
    }

}
